import pika
import json
from qywx import sendMsg,kickout_group,active_wxwork_search_window
import lxlog
import lxconfig
from LXWindowUtil import screenshot,find_window_handle,click_window_by_image,locate_on_screen
import threading
import time

class RabbitMQConsumer:
    def __init__(self):
        mqconfig = lxconfig.get('rabbitmq')
        self.host = mqconfig['host']
        self.delay_queue = mqconfig['delay_queue']
        self.update_msg_status_queue=mqconfig['update_msg_status_queue']
        self.update_group_kickout_status_queue = mqconfig['update_group_kickout_status_queue']
        self.relogin_queue = 'relogin_queue'
        self.connection = None
        self.channel = None
       
        def task():
            lxlog.set_trace_id()
            lxlog.set_log_level(2)
            num=0
            while True:
                time.sleep(10)
                try: 
                    x,y = locate_on_screen(r'wxqjss.png',region=(320,70, 66, 80), log=False) # 判断全局搜索框是否存在
                    if x is None or y is None:
                        # lxlog.info(f"未找到全局搜索框!")
                        x,y = locate_on_screen(r'reloginss.png', log=False) #判断有没有微信搜索框
                        if x is None or y is None:
                            click_window_by_image(r'relogin.png',grayscale=True,confidence=0.8, log=False) # 判断确定按钮
                            click_window_by_image(r'refresh.png',grayscale=True,confidence=0.8, log=False) # 判断刷新二维码
                            num+=1
                            if num%6==0: #60秒内都是没有找到全局搜索框
                                self.send_relogin_message({'msg':'掉线！'})
                        else:
                            active_wxwork_search_window() #打开搜索框
                            num=0
                    screenshot() # 截图
                except Exception as e:
                    lxlog.error(f'定时监听桌面出错: {str(e)}')

        # 启动线程
        thread = threading.Thread(target=task)
        thread.daemon = True  # 设置为守护线程，主程序退出时会自动结束
        thread.start()

    def connect(self):
        try:
            self.connection = pika.BlockingConnection(pika.ConnectionParameters(host=self.host))
            self.channel = self.connection.channel()
            # 创建延迟交换机和队列
            self.channel.exchange_declare(exchange='delay_exchange', exchange_type='x-delayed-message', durable=True, auto_delete=False, arguments={'x-delayed-type': 'direct'})
            self.channel.queue_declare(queue=self.delay_queue, durable=True, auto_delete=False)
            self.channel.queue_bind(exchange='delay_exchange', queue=self.delay_queue, routing_key=self.delay_queue)
            
            self.channel.queue_declare(queue=self.relogin_queue, durable=True, auto_delete=False)
            self.channel.queue_bind(exchange='delay_exchange', queue=self.relogin_queue, routing_key=self.relogin_queue)
            
            lxlog.info(f'成功创建延迟队列: {self.delay_queue}')
            
            lxlog.info(f'成功连接到RabbitMQ服务器: {self.host}')
            return True
        except Exception as e:
            lxlog.info(f'连接RabbitMQ服务器失败: {str(e)}')
        return False

    def callback(self, ch, method, properties, body):
        try:
            screenshot(imageFilename='image/screenshot_callback.png')
            lxlog.info(f'\n\n收到消息: {body.decode("utf-8")}')
            message = json.loads(body.decode('utf-8'))
            traceId = message.get('traceId', None)
            lxlog.set_trace_id(traceId)

            type = message.get('type', 'msg')
            if type == 'msg': # 发送企业微信消息
                self.callQywx(message)
                mmrId = message.get('mmrId', '')
                self.send_update_msg_status_message({'mmrId': mmrId, 'traceId': traceId})
            elif type == 'kickout': # 群踢人
                group= message.get('group', '')
                users = message.get('users', '')
                dusers = kickout_group(group_name=group,users=users)
                message['users']= dusers
                self.send_update_group_kickout_status_message(message)
            elif type == 'debug': # 修改日志等级
                lxlog.set_log_level(0)
            elif type == 'info': # 修改日志等级
                lxlog.set_log_level(1)
        except Exception as e:
            lxlog.error(f'处理消息时出错: {str(e)}')
            screenshot(imageFilename='image_screenshot_error.png')
        try:
            ch.basic_ack(delivery_tag=method.delivery_tag)
        except Exception as e1:
            print('rabbitmq错误!')
    def callQywx(self,message):
        group_name = message.get('group', '')
        msgs = message.get('msgs', None)
        at = message.get('at', None)
        time = message.get('time', None)
        if time is None or not self.is_within_half_hour(time):
            lxlog.info(f'消息时间 {time} 不在当前时间前后半小时内，跳过处理')
            return
        if group_name:
            sendMsg(group_name=group_name, msgs=msgs, at=at)
        else:
            lxlog.error('消息格式不正确，缺少必要字段')
    def send_relogin_message(self, message,delay_time=0):
        if self.channel and self.delay_queue:
            properties = pika.BasicProperties(
                headers={'x-delay': delay_time}
            )
            self.channel.basic_publish(
                exchange='delay_exchange',
                routing_key=self.relogin_queue,
                body=json.dumps(message,ensure_ascii=False),
                properties=properties
            )
            lxlog.info(f'已发送延迟消息到队列: {self.relogin_queue}')
    def send_update_msg_status_message(self, message,delay_time=0):
        if self.channel and self.delay_queue:
            properties = pika.BasicProperties(
                headers={'x-delay': delay_time}
            )
            self.channel.basic_publish(
                exchange='delay_exchange',
                routing_key=self.update_msg_status_queue,
                body=json.dumps(message,ensure_ascii=False),
                properties=properties
            )
            lxlog.info(f'已发送延迟消息到队列: {self.update_msg_status_queue}')
    def send_update_group_kickout_status_message(self, message,delay_time=0):
        if self.channel and self.delay_queue:
            properties = pika.BasicProperties(
                headers={'x-delay': delay_time}
            )
            self.channel.basic_publish(
                exchange='delay_exchange',
                routing_key=self.update_group_kickout_status_queue,
                body=json.dumps(message, ensure_ascii=False),
                properties=properties
            )
            lxlog.info(f'已发送延迟消息到队列: {self.update_group_kickout_status_queue}')
    def start_consuming(self):
        if self.channel:
            lxlog.info(f'开始监听延迟队列: {self.delay_queue}')
            self.channel.basic_consume(queue=self.delay_queue, on_message_callback=self.callback)
            self.channel.start_consuming()
        else:
            lxlog.info('未建立连接，无法开始消费消息')

    # 检查时间是否在当前时间前后半小时内
    def is_within_half_hour(self, time_str):
        from datetime import datetime, timedelta
        try:
            target_time = datetime.strptime(time_str, '%Y-%m-%d %H:%M:%S')
            now = datetime.now()
            return abs((target_time - now).total_seconds()) <= 1800
        except Exception as e:
            lxlog.error(f'解析时间失败: {str(e)}')
            return False

    def close(self):
        try:
            if self.connection and not self.connection.is_closed:
                self.connection.close()
                lxlog.info('已关闭RabbitMQ连接')
        except Exception as e:
            lxlog.error(f'关闭连接时出错: {str(e)}')
        finally:
            self.connected = False

if __name__ == '__main__':
    consumer = RabbitMQConsumer()
    while True:
        try:
            if consumer.connect():
                consumer.start_consuming()
            else:
                lxlog.error('连接失败，等待重试...')
                time.sleep(5)
        except KeyboardInterrupt:
            lxlog.info('正在停止消费者...')
            break
        except Exception as e:
            lxlog.error(f'消费者运行出错: {str(e)}，尝试重新连接...')
            consumer.close()
            time.sleep(5)


